package com.imis.tea.core.dao.plugin;

import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.imis.tea.core.dao.constants.StatementConstants;
import com.imis.tea.core.dao.sqlsource.DeleteSqlSource;
import com.imis.tea.core.dao.sqlsource.SaveSqlSource;
import com.imis.tea.core.dao.sqlsource.UpdateSqlSource;
import com.imis.tea.core.dao.sqlsource.UpdateWithOptimisticLockSqlSource;
import com.imis.tea.core.utils.common.TeaUtils;

/**
 * 
 * @author wf.shu
 * @since 2017年10月30日 下午3:19:53
 */
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class}) })
public class UpdatePlugin implements Interceptor {
	/**
	 * 日志处理
	 */
	protected final Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 
	 * @author wf.shu
	 * @since 2017年10月30日 下午3:19:50
	 * @param invocation
	 * @return
	 * @throws Throwable
	 * @see org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin.Invocation)
	 */
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		MappedStatement statement = (MappedStatement) invocation.getArgs()[0];
		Object paramObject = invocation.getArgs()[1];
		if(StatementConstants.STATEMENT_SAVE_ID.endsWith(statement.getId())){
			SqlSource sqlSource = new SaveSqlSource(statement.getConfiguration(), statement.getBoundSql(paramObject), paramObject);
			TeaUtils.setFieldValue(statement, "sqlSource", sqlSource);
		}
		if(StatementConstants.STATEMENT_UPDATE_ID.endsWith(statement.getId())){
			SqlSource sqlSource = new UpdateSqlSource(statement.getConfiguration(), statement.getBoundSql(paramObject), paramObject);
			TeaUtils.setFieldValue(statement, "sqlSource", sqlSource);
		}
		if(StatementConstants.STATEMENT_UPDATEWITHOPTIMISTICLOCK_ID.endsWith(statement.getId())){
			UpdateWithOptimisticLockSqlSource sqlSource = new UpdateWithOptimisticLockSqlSource(statement.getConfiguration(), statement.getBoundSql(paramObject), paramObject);
			TeaUtils.setFieldValue(statement, "sqlSource", sqlSource);
			invocation.getArgs()[1] = sqlSource.getParameterObject();
		}
		if(StatementConstants.STATEMENT_DELETE_ID.endsWith(statement.getId())){
			SqlSource sqlSource = new DeleteSqlSource(statement.getConfiguration(), statement.getBoundSql(paramObject), paramObject);
			TeaUtils.setFieldValue(statement, "sqlSource", sqlSource);
		}
		logger.info("statement:" + statement.getBoundSql(paramObject).getSql());
		return invocation.proceed();
	}

	/**
	 * 
	 * @author wf.shu
	 * @since 2017年10月30日 下午3:20:09
	 * @param target
	 * @return
	 * @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object)
	 */
	
	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}
	/**
	 * 
	 * @author wf.shu
	 * @since 2017年10月30日 下午3:20:13
	 * @param properties
	 * @see org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties)
	 */
	@Override
	public void setProperties(Properties properties) {
	}

}
